/* ====================================================================
 * (#)Header: ExternallyPaginatedListCommand.java
 * (#)Revision: 
 * (#)Date Created: June 11, 2009 12:07:22 AM
 * (#)Created By: Karol Wozniak
 * ====================================================================
 *
 * Copyright (c) 2007 karolak .  All rights reserved.
 *
 * ====================================================================
 * 
 * The software application represented here is the sole property of 
 * karolak. Its unauthorized utilization is expressly prohibited.
 * 
 * ====================================================================
 */
package com.karolak.web.saf.command;

import java.util.List;

import org.displaytag.tags.TableTagParameters;
import org.displaytag.util.ParamEncoder;

import com.karolak.constants.SortOrder;
import com.karolak.query.Criterias;
import com.karolak.service.Service;
import com.karolak.web.saf.action.ModelAction;

/**
 * <code>ExternallyPaginatedListCommand</code> is used to ....
 * 
 * @author <a href="mailto:kwozniak@hotmail.com">Karol Wozniak</a>
 */
public class ExternallyPaginatedListCommand implements ActionCommand {

	public <T, Id, S extends Service<T, Id>> void prepare(ModelAction<T, Id, S> action) {

	}

	public <T, Id, S extends Service<T, Id>> void validate(ModelAction<T, Id, S> action) {

	}

	public <T, Id, S extends Service<T, Id>> String execute(ModelAction<T, Id, S> action) {
		String tableId = "entity";
		int paginationSize = 25;
		try {
			// TODO consider caching page size for different pages (configurable
			// by user on page)
			paginationSize = Integer.parseInt("" + action.getSession().get("paginationSize"));
		} catch (Exception e) {
		}

		String orderBy = getOrderByPropertyName(action, tableId);
		SortOrder sortOrder = getSortOrder(action, tableId);
		int pageNumber = getPageNumber(action, tableId);

		int listSize = action.getService().selectCount();
		action.getRequest().put("listSize", listSize);
		int startingIndex = (pageNumber - 1) * paginationSize;
		List<T> list = null;
		if (orderBy != null) {
			Criterias criterias = new Criterias();
			criterias.addOrderBy(orderBy, sortOrder.toString());
			list = action.getService().select(criterias, startingIndex, paginationSize);
		} else {
			list = action.getService().select(startingIndex, paginationSize);
		}
		action.setEntities(list);
		return "list";
	}

	protected <T, Id, S extends Service<T, Id>> String getOrderByPropertyName(ModelAction<T, Id, S> action, String tableId) {
		String orderBy = null;
		String orderByParamName = new ParamEncoder(tableId).encodeParameterName(TableTagParameters.PARAMETER_SORT);
		if (orderByParamName != null) {
			Object o = action.getParameters().get(orderByParamName);
			if (o != null) {
				String[] params = (String[]) o;
				if (params.length > 0) {
					orderBy = params[0];
				}
			}
		}
		return orderBy;
	}

	protected <T, Id, S extends Service<T, Id>> SortOrder getSortOrder(ModelAction<T, Id, S> action, String tableId) {
		String sortOrderParamName = new ParamEncoder(tableId).encodeParameterName(TableTagParameters.PARAMETER_ORDER);
		SortOrder sortOrder = SortOrder.ASC;
		if (sortOrderParamName != null) {
			Object o = action.getParameters().get(sortOrderParamName);
			if (o != null) {
				String[] params = (String[]) o;
				if (params.length > 0) {

					if ("1".equals(params[0])) {
						sortOrder = SortOrder.DESC;
					}
				}
			}
		}
		return sortOrder;
	}

	protected <T, Id, S extends Service<T, Id>> int getPageNumber(ModelAction<T, Id, S> action, String tableId) {
		String pageNumberParamName = new ParamEncoder(tableId).encodeParameterName(TableTagParameters.PARAMETER_PAGE);
		int pageNumber = 1;

		if (pageNumberParamName != null) {
			Object o = action.getParameters().get(pageNumberParamName);
			if (o != null) {
				String[] params = (String[]) o;
				if (params.length > 0) {
					try {
						pageNumber = Integer.parseInt(params[0]);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		return pageNumber;
	}
}
